package com.treasure.infrastructure.domain.impl.client;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.treasure.common.exception.ParameterException;
import com.treasure.common.types.Corp;
import com.treasure.infrastructure.model.po.CorpEmailAccount;
import com.treasure.infrastructure.repository.dao.mapper.CorpEmailAccountMapper;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.mail.*;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.List;
import java.util.Objects;
import java.util.Properties;

/**
 * @author sunhongmin
 * @date 2023/11/5 11:42
 * @description
 */
@Service
@Slf4j
public class EmailSenderClientImpl implements EmailSenderClient {
    @Resource
    private JavaMailSenderImpl javaMailSender;
    @Resource
    private CorpEmailAccountMapper corpEmailAccountMapper;

    @Override
    public void sendTextMailMessage(List<String> to, String subject, String text) {
        EmailSender emailSender = new EmailSender(javaMailSender.getHost(), javaMailSender.getUsername(), javaMailSender.getPassword());
        doEmailSend(to, subject, text, emailSender);
    }

    @Override
    public void sendTextMailMessage(Corp corp, List<String> to, String subject, String text) {
        QueryWrapper<CorpEmailAccount> emailAccountQuery = new QueryWrapper<>();
        emailAccountQuery.lambda().eq(CorpEmailAccount::getCorpId, corp.getValue());
        CorpEmailAccount corpEmailAccount = corpEmailAccountMapper.selectOne(emailAccountQuery);
        if (Objects.isNull(corpEmailAccount)) {
            throw new ParameterException("企业/高校未配置邮箱发送账号，请联系管理员前往管理后台配置");
        }
        EmailSender emailSender = new EmailSender(corpEmailAccount.getHost(), corpEmailAccount.getEmailName(), corpEmailAccount.getePassword());
        doEmailSend(to, subject, text, emailSender);
    }

    public static void doEmailSend(List<String> to, String subject, String text, EmailSender emailSender) {
        Session mailSession = getMailSession(emailSender.getEmailName(), emailSender.getPassword(), emailSender.getHost());
        Message message = new MimeMessage(mailSession);
        try {
            message.setFrom(new InternetAddress(emailSender.getEmailName()));
            message.setRecipients(MimeMessage.RecipientType.TO, convertToRecipients(to));
//            message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(emailSender.getEmailName()));
            // 设置抄送人, 避免被网易邮箱列为垃圾邮件
//            message.setRecipient(Message.RecipientType.CC, new InternetAddress(emailSender.getEmailName()));
            // 主题（标题）
            message.setSubject(subject);
            // 设置编码，防止中文乱码
            message.setContent(text, "text/html;charset=UTF-8");
            Transport.send(message);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

    @NotNull
    private static Address[] convertToRecipients(List<String> to) throws AddressException {
        if (CollectionUtils.isEmpty(to)) {
            throw new ParameterException("邮件缺少接收人");
        }
        Address[] recipients = null;
        recipients = new InternetAddress[to.size()];
        for (int i = 0; i < to.size(); i++) {
            recipients[i] = new InternetAddress(to.get(i));
        }
        return recipients;
    }

    public static Session getMailSession(String userName, String password, String host) {
        Properties properties = new Properties();
        properties.setProperty("mail.host", host);
        properties.setProperty("mail.smtp.auth", "true");
        properties.setProperty("mail.debug", "true");
        Authenticator authenticator = new Authenticator() {
            @Override
            public PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(userName, password);
            }
        };
        return Session.getDefaultInstance(properties, authenticator);
    }

    @AllArgsConstructor
    @Getter
    public static class EmailSender {
        private String host;
        private String emailName;
        // 授权码，不是登录密码
        private String password;
    }

}
